Skip to content

Add additional guardrails against unsigned underflows caused by wrong WordCount#3787

Merged
MrSidims merged 2 commits into
KhronosGroup:mainfrom
maarquitos14:maronas/wordcount-guardrails
Jul 9, 2026
Merged

Add additional guardrails against unsigned underflows caused by wrong WordCount#3787
MrSidims merged 2 commits into
KhronosGroup:mainfrom
maarquitos14:maronas/wordcount-guardrails

Conversation

@maarquitos14

Copy link
Copy Markdown
Contributor

Following up on #3671, this adds additional guardrails for cases that were still unhandled by the previous patch. This PR also includes multiple new tests for invalid wordcounts, and joins them all --the new, and the ones added by #3671-- in their own directory (test/negative/invalid-wordcount).

@MrSidims MrSidims left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the vulnerability exposed only for text SPIR-V form or for binary form as well?

I feel like that the fix is built under an assumption, that the 1st Word of the instruction is the OpCode. It's not. The first Word is OpCode plus the instruction's words count (16 bits each for a 32-bit word). Should we be checking, that the encoded word count is legit instead (per each instruction) (I kinda feel, that llvm-spirv is already doing that).

@maarquitos14

Copy link
Copy Markdown
Contributor Author

Is the vulnerability exposed only for text SPIR-V form or for binary form as well?

It's exposed for both formats.

I feel like that the fix is built under an assumption, that the 1st Word of the instruction is the OpCode. It's not. The first Word is OpCode plus the instruction's words count (16 bits each for a 32-bit word). Should we be checking, that the encoded word count is legit instead (per each instruction) (I kinda feel, that llvm-spirv is already doing that).

I don't think the fix assumes that. The core of the fix is

// Reject a WordCount below the instruction's minimum before setWordCount().
  if (!M.getErrorLog().checkError(WordCount >= Entry->getFixedWordCount(),
                                  SPIRVEC_InvalidWordCount,
                                  "WordCount is smaller than the instruction's "
                                  "minimum word count")) {
    M.setInvalid();
    delete Entry;
    return nullptr;
  }

and the rest is just making sure that getFixedWordCount() is available and correct for every SPIRVEntry. For all the cases except one, we're reusing the FixedWC class member. Can you help me understand why you think the fix is built under such an assumption?

@MrSidims

MrSidims commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

@maarquitos14 please address CI complaints.

#3840 should be merged first to avoid translation time regression.

@vmaksimo @svenvh @YuriPlyakhin please take a look. While I do believe, that the better approach is to enforce spirv-val before consuming SPIR-V module, yet the issue this PR addresses is real as underflow can cause CWE-789.

I'll check what would be the cost of enabling spirv-val as optional validation layer be llvm-spirv (probably we would need some customizations).

@YuriPlyakhin YuriPlyakhin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@MrSidims MrSidims merged commit a1441b2 into KhronosGroup:main Jul 9, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants